                   USING EXPANSION RAM IN SMARTLOGO
                           By Guy Cousineau
 
First,  let  me  say  that  I  am  not  a  LOGO  expert.  
Some of the       techniques  described  in  this  article  
may not be the most practical       and/or efficient way  of  
doing  things.  I have, however, discovered a       
rudimentary way of accessing expansion RAM in LOGO.
 
First, some technical stuff.  LOGO can  use the memory area 
below 31740  for  machine  language  routines.  Bytes are 
reserved via the .ALLOCATE primitive. Expansion RAM can be 
switched  in  in  halves  -  the  part residing  from 0  to  32767 
 OR  the  part  residing between 32768 and 65535.  In order  
to     pass  values  from standard RAM to EXPANSION RAM,  
one must use this two step approach so that one part of the 
controlling  program has access to 1/2 of    the REAL memory 
before taking over.
 
Thus the approach I used:  set up a  machine  language  
routine  in the lower half which will  get  the  ADDRESS TO 
PEEK/POKE and the value (if POKE). This machine language routine  
switches  in  the  upper half of  ERAM and sends    that 
information  to  another controlling routine.  When  this second 
routine takes over, it switches  in  the lower half of ERAM  
and executes the  PEEK   or  POKE.  Everything is then 
switched back to  normal settings.
 
This presented me with quite a complex  problem:  how  to 
POKE all that       machine language stuff into  memory.  I 
wrote the drivers (in CP/M) and       assembled them creating a 
PRN file  which  had  all the POKE values (in HEX). Problem 
number two:  how  to  POKE HEX values using LOGO.  After quite 
a bit  of work, I came up with  the procedures which you 
will find  in the SETERAM   LOGO file on this disk.
 
Following this  article,  you  will  find the complete 
machine language       source listing  for  the  routines  
required.  It  is  divided  into  5       components:
 
SENDBYTE is the routine which will  send  a  byte to the 
expansion RAM.  It   extracts the address from  31738-31739 and 
the value from 31740.  It  then    jumps to the controlling 
routine  in  expansion  RAM which handles  the       actual 
transfer.
 
GETBYTE is the reverse  function  which gets a value from 
expansion RAM  and  places it in address 31740 where  LOGO  can 
 extract it for further  use.
 
The  next  two  routines  are  the  companion  drivers  to 
SENDBYTE and       GETBYTE.  They switch in the  other  half 
of expansion RAM and move the  byte in question.  They then 
return  control  to the calling routine in  regular   memory.
 
The last  routine  is  the  one  used  by LOGO to move the 
drivers into       expansion RAM.  It is not required after 
its first use.
 
 
 The LOGO  program  contains  a  procedure  to  move  the  
drivers  into      expansion RAM.  Another procedure POKES  
the  controlling  program into       standard memory.  Both  of 
 these  use a somewhat verbose HEX procedure  to   POKE 
values starting at a particular  address from a LIST containing  
HEX     values.  It calls the  CONV  procedure to change 
these numbers into  decimal  prior to using .DEPOSIT.
 
The program then defines two  procedures:  PEEKERAM  and  
POKEERAM  and gives you the syntax for using them....all  
values  are decimal at this point.  The final step  is  to  erase  
the procedures which will not be required....only  PEEKERAM 
and POKEERAM  remain  and  can be merged into other programs. 
 Since the program  is self destructive, I did not make  it 
AUTORUN by using ' MAKE  "STARTUP  "START '.  To get it 
running, type  the following:
        LOAD "SETERAM           (wait)
        START
 
You can then try the following to ensure that it is working:
 
        PEEKERAM 1000
        PRINT [PEEK]
        POKEERAM 1000 50
        PEEKERAM 1000
        PRINT [PEEK]
 
WARNING!  do  not  POKEERAM  between  8000H  and 80FFH, 
32768 and 33023       inclusive.  This is where the  controlling 
routines reside.  I will let  the  LOGO experts improve the 
POKEERAM  routine  to disable POKES within  that     range.
 
Now  for  the  potential  problem:  Demons  and  other  such 
things.  I       presume  that  LOGO  uses  interrupts  to  
handle  DEMONS, and keyboard       scanning for ESCAPE, and  
perhaps  a  few other things.  When the upper  half of ERAM 
is switched in, part of  the LOGO program disappears and a  
branch to a DEMON  routine  would  create havoc.  Furthermore, 
when the  lower half of  ERAM is also switched  in, a NON 
MASKABLE INTERRUPT would  branch  to  66H.   This  could  be  
halted  with a 'RET NMI' instruction  POKED into  66H  of    
ERAM  (there's  another address we can't use.)  If  other 
interrupts are      used, where do  they  branch.  I will let the 
LOGO  experts work on that.     Enjoy the routines.
 
Guy Cousineau 1059 Hindley Street OTTAWA Canada K2B 5L9
        OTTAWA RCPM (613) 952-2289

                        ;ERAM driver for LOGO
                        ;31740=byte to put if POKE or 
recieved byte if PEEK
                        ;31738, 31739= ERAM address to work 
with
                        ;
                        ;the LOGO routine must place valid 
bytes in these
                        ;prior to making the ".call"
                        ;it should also check that the area 
                        ;from 8000H and 8100H is NOT used
                        ;that is where the drivers reside.
                        ;
          7BCE          STARTAT EQU      31738-TRANSLENGTH
                                        .PHASE  STARTAT
                        ;
                        SENDBYTE:                       
;=31694 *****
  7BCE  3E 09                   LD      A,9             
;switch upper half in
  7BD0  D3 7F                   OUT     (127),A
  7BD2  3A FC 7B                LD      A,(31740)       ;get 
byte to send
  7BD5  ED 5B FA 7B             LD      DE,(31738)      
;address to send it
  7BD9  21 DF 7B                LD      HL,GETBACK1     
;make sure we getback
  7BDC  C3 00 80                JP      8000H           
;jump to e-ram
                                GETBACK1:
  7BDF  3E 01                   LD      A,1
  7BE1  D3 7F                   OUT     (127),A         
;back to normal RAM
  7BE3  C9                      RET
                        ;
                        GETBYTE:                        
;=31716 *****
  7BE4  3E 09                   LD      A,9
  7BE6  D3 7F                   OUT     (127),A         
;switch upper half
  7BE8  ED 5B FA 7B             LD      DE,(31738)      
;address to read from
  7BEC  21 F2 7B                LD      HL,GETBACK2
  7BEF  C3 80 80                JP      8080H
                                GETBACK2:
  7BF2  32 FC 7B                LD      (31740),A       ;put 
byte where LOGO 
                                                        ;can 
read it
  7BF5  3E 01                   LD      A,1
  7BF7  D3 7F                   OUT     (127),A
  7BF9  C9                      RET     
                        ;
                        TRANSLENGTH     EQU     $-SENDBYTE
                                .dephase
                        ;
                        ;driver section which must be loaded 
to e-ram
                                .PHASE  8000H
                        ;put byte section pokes (DE) with A
  8000  0E 7F                   LD      C,127
  8002  06 0A                   LD      B,10
  8004  ED 41                   OUT     (C),B           
;switch lower half
  8006  12                      LD      (DE),A
  8007  06 09                   LD      B,9
  8009  ED 41                   OUT     (C),B
  800B  E9                      JP      (HL)            
;back to original 
                                                        
;caller exit routine
                        ;
                                .dephase

                                .phase  8080H
                        ;
                        ;get byte routine PEEKS (DE)
                        ;
  8080  0E 7F                   LD      C,127
  8082  06 0A                   LD      B,10
  8084  ED 41                   OUT     (C),B           
;switch lower half
  8086  1A                      LD      A,(DE)
  8087  06 09                   LD      B,9
  8089  ED 41                   OUT     (C),B
  808B  E9                      JP      (HL)            
;back to caller
                        ;
                                .dephase
                        ;
                        ;now we need a ML routine to POKE 
the ML routine
                        ;I.E.  switch in the upper half and 
move data
                        ;       from    somewhere below 
31737
                        ;       to                      
32768   (8000H)
                        ;
                        ;since drivers may be expanded to 
cover larger erams
                        ;I have allowed 80H bytes of code 
for each driver
                        ;so we POKE the destination address 
at 31738,31739
                        ;this will be 8000H for part 1 and 
8080H for part 2
                        ;
                        ;our data needs to be poked in 
                        ;below the routine that will 
transfer it
                        ;the routine below is  bytes long
                        ; 
                        ;so our data starts at 31738-80H-15H
                        ;        or 31589....remember that 
number
                        ;        we'll use in in the 
".DEPOSIT" routine
                        ;
                                .phase 31738-15H
  7BE5                  routinestart                    
;31717  *****
  7BE5  3E 09                   LD      A,9
  7BE7  D3 7F                   OUT     (127),A
  7BE9  21 65 7B                LD      HL,31589
  7BEC  ED 5B FA 7B             LD      DE,(31738)
  7BF0  01 80 00                LD      BC,80H
  7BF3  ED B0                   LDIR
  7BF5  3E 01                   LD      A,1
  7BF7  D3 7F                   OUT     (127),A
  7BF9  C9                      RET
          7BFA          end routine      equ     $
          0015          routine len      equ     


